package cn.ztydata.teachingsystem.heaven.dao.redis;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.List;


/**
 * 学生资源收藏
 *
 * @author lyj
 * @since 2015/3/31
 */
@Repository
public class StudentRscDao extends BaseRedisDao{

    protected static Logger logger = LoggerFactory.getLogger(BaseRedisDao.class); //日志记录器


    /**
     * 保存学生收藏的资源
     *
     * @param studentId 教师编号
     * @param rscId 资源编号
     * @return Boolean
     * @author lyj
     * @since 2015-3-31
     */
    public Boolean addResource(final long studentId, final long rscId, final long groupId, final int groupType) {
        SessionCallback<Boolean> sessionCallback = new SessionCallback<Boolean>() {
            @Override
            public Boolean execute(RedisOperations operations) throws DataAccessException {
                operations.multi();

                //获取Set操作
                SetOperations<String, Long> setOperations = operations.opsForSet();

                //获取List操作
                ListOperations<String,Long> listOperations = operations.opsForList();

                //保存学生与资源的关系
                listOperations.rightPush(KeyUtils.studentRsc(studentId, groupType, groupId), rscId);

                //保存资源与学生的关系
                setOperations.add(KeyUtils.rscStudent(rscId, groupType, groupId), studentId);

                operations.exec();
                return true;
            }
        };

        logger.debug("保存学生收藏的资源");
        return (Boolean)redisTemplate.execute(sessionCallback);
    }

    /**
     * 判断资源是否已经被收藏
     *
     * @param  studentId 学生ID
     * @param rscId 资源ID
     * @return Boolean
     * @author lyj
     * @since 2015-03-31
     */
    public Boolean isCollected(final long studentId, final long rscId, final long groupId, final int groupType){
        SetOperations<String,Long> listOperations = redisTemplate.opsForSet();

        logger.debug("判断资源是否已经被收藏");
        return listOperations.isMember(KeyUtils.rscStudent(rscId, groupType, groupId), studentId);
    }


    /**
     * 获取所有资源id
     * @param studentId 学生ID
     * @return List
     *
     * @author lyj
     * @since 2015-4-1
     */
    public List<Long> getAll(final long studentId, final long groupId, final int groupType) {
        ListOperations<String, Long> listOperations = redisTemplate.opsForList();

        logger.debug("获取所有资源id");
        return listOperations.range(KeyUtils.studentRsc(studentId, groupType, groupId), 0, -1);
    }

    /**
     * 获取所有资源id
     * @param studentId 学生ID
     * @param groupType 群组类型
     * @param groupIds 群组编号
     * @return List
     *
     * @author fanruiping
     * @since 2015-05-07
     */
    public List<Long> getAll(final long studentId, final int groupType,final List<Long> groupIds) {
        ListOperations<String, Long> listOperations = redisTemplate.opsForList();

        List<Long> resourceIds = new ArrayList<>();

        //群组编号集合为空或群组类型部位课程群组和班级群组
        if(groupIds.isEmpty() || (groupType != 1 && groupType != 3)){
            logger.debug("群组编号集合为空或群组类型部位课程群组和班级群组");

            return resourceIds;
        }

        logger.debug("循环获取资源编号:Long groupId : groupIds");
        //循环获取资源编号
        for (Long groupId : groupIds){
            resourceIds.addAll(listOperations.range(KeyUtils.studentRsc(studentId,groupType,groupId),0,-1));
        }

        return resourceIds;
    }

    /**
     * 删除学生收藏资源(一个)
     *
     * @param studentId 学生ＩＤ
     * @param resourceId 资源ＩＤ
     * @return Boolean
     * @author lyj
     * @since 2015-4-3
     */
    public Boolean deleteResource(final long studentId, final long resourceId, final long groupId, final int groupType) {
        SessionCallback<Boolean> sessionCallback = new SessionCallback<Boolean>() {
            @Override
            public Boolean execute(RedisOperations operations) throws DataAccessException {
                operations.multi();

                //获取Set操作
                SetOperations<String, Long> setOperations = operations.opsForSet();

                //获取List操作
                ListOperations<String, Long> listOperations = operations.opsForList();

                //删除教师收藏的资源
                listOperations.remove(KeyUtils.studentRsc(studentId, groupType, groupId), 0, resourceId);

                setOperations.remove(KeyUtils.rscStudent(resourceId, groupType, groupId), studentId);

                operations.exec();
                return true;
            }
        };

        logger.debug("删除学生收藏资源(一个)");
        return (Boolean)redisTemplate.execute(sessionCallback);
    }

}
